iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
Modern Web

開始搞懂React生態系系列 第 19

Day 19 全站狀態管理的利器 - Redux (一) Store and Action

  • 分享至 

  • xImage
  •  

為什麼要用 Redux

當專案中的階層越來越複雜,資料在多層元件之間的傳遞就越來越多,一般使用 props 層層傳遞的方式,但並不是每個元件都需要去使用該 props,且這樣的方式會造成程式碼管理追蹤更為複雜,在之前介紹了 React Context 來改善層層傳遞 props 的做法, Context 會有整個作用範圍的 Re-Render的效能問題。

若專案是簡單的應用,使用前面介紹的 useReducer 或是 React Context,就不需要用上 Redux。但專案越來越複雜時,就可以考慮 Redux。

Redux 主要解決狀態管理的二個問題

  1. 避免過多的 props 層層傳遞 (Prop Drilling)
  2. 避免不必要的 Re-Render

安裝

Redux 不是 React 官方內建的函式庫,所以使用前要先安裝。

npm install redux react-redux

Redux 不是專屬於 React 使用,原生的 JS 或是其他前端框架都可以引入使用。

使用在 React 上的話, 就要安裝 Redux 與 React 的綁定使用套件 react-redux

Redux API 重點

分別是 Store、Actions、Reducer

因為一次詳細介紹完會讓文章變得太長不易閱讀,所以我們在本篇先介紹 Store 跟 Actions,下一篇再介紹 Redcuer。

Redux Store

Store 會是應用程式集中管理資料狀態的地方。我們會建立 Store 然後把它提供給 React App 使用。

  • 建立 Store 模組
// src/store/index.js
import {createStore} from 'redux';
...
const store = createStore(...);
...
export default store;
  • 提供 Store 給 React App 使用
// src/index.js
import { Provider } from 'react-redux';
import { App } from './App';

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <Provider store={store}>
    <App />
  </Provider>
)

Actions

Store 裡的狀態,只能被單向的更新,想要更新 State,就必需要發出 (Dispatch) 一個動作 (Action) 來表達意圖,有的時候 Action 會伴隨一些資料 (Payload),用以做邏輯處理。

Dispatch Action

使用 useDispatch 取得 React-Redux 的 dispatch 函式,然後在元件中使用下面的方式,發出 Action

// 在元件中使用
import {useDispatch} from 'react-redux';
const dispatch = useDispatch();
...
dispatch({
  type: 'ADD_TODO',
  text: 'Build my first Redux app'
})
...
dispatch({
  type: 'REMOVE_TODO',
  index: 5
})

字串常數定義 Action Type

我們通常會用字串常數先去定義好這些 Action Type,然後將其移進一個單獨的模組,然後再使用它們。

// 在元件中使用

/*
 * action type
 */
export const ADD_TODO = 'ADD_TODO';
export const REMOVE_TODO = 'REMOVE_TODO';
...
dispatch({
  type: ADD_TODO,
  text: 'Build my first Redux app'
})
...
dispatch({
  type: REMOVE_TODO,
  index: 5
})

對小專案來說,直接使用字串當作 action type 可能更簡單一些。不過,在較大的專案中使用明確定義的字串常數有一些好處,取決於專案的複雜度。

Action Creators

我們可以把 dispatch action 的寫法,寫得更優雅。
這樣的寫法會讓它們更具有移植性並易於測試。

// src/actions/index.js

/*
 * action type
 */
export const ADD_TODO = 'ADD_TODO';
export const REMOVE_TODO = 'REMOVE_TODO';

export const addTodo = (text) => {
  return {
    type: ADD_TODO,
    text
  }
} 

export const removeTodo = (index) => {
  return {
    type: REMOVE_TODO,
    index
  }
} 
// 在元件中使用
import { addTodo, removeTodo } from './actions';
...
dispatch(addTodo(text))
dispatch(removeTodo(index))

Actions 描述要發生修改State的動作/規則,但並不指定應用程式的 State 要如何去應對改變,這是 Reducer 的工作。

Next

因為一次詳細介紹完會讓文章變得太長不易閱讀,所以我們在本篇先介紹 Store 跟 Actions,下一篇再介紹 Redcuer。

Reference

https://www.freecodecamp.org/news/what-is-redux-store-actions-reducers-explained/

https://www.laitimes.com/article/1od0a_1u849.html

https://chentsulin.github.io/redux/index.html

https://pjchender.dev/webdev/note-without-redux/

https://ithelp.ithome.com.tw/articles/10219962


上一篇
Day 18 多層級元件間的狀態管理 - Context & useContext
下一篇
Day 20 全站狀態管理的利器 - Redux (二) Reducer
系列文
開始搞懂React生態系30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言